﻿/*
 * Created by: 
 * Created: Monday, May 28, 2007
 */

using System;
using System.Collections.Generic;
using Dune.Common.ControlFlow;
using Dune.Common.Utils;

namespace Dune.Business.Domain.Filters
{
    public class SimpleFiltersManager : IFiltersManager
    {
        protected class FilterHolder
        {
            private readonly FilterDescription filterDescription;
            private readonly BaseFilter filterInstance;


            public FilterHolder(FilterDescription filterDescription, BaseFilter filterInstance)
            {
                if (filterDescription == null)
                    throw new ArgumentException("filterDescription");

                if (filterInstance == null)
                    throw new ArgumentException("filterInstance");

                this.filterDescription = filterDescription;
                this.filterInstance = filterInstance;
            }


            public FilterDescription FilterDescription
            {
                get { return filterDescription; }
            }

            public BaseFilter FilterInstance
            {
                get { return filterInstance; }
            }
        }

        private Dictionary<Type, List<FilterHolder>> typesHolders = new Dictionary<Type, List<FilterHolder>>();

        public ICollection<FilterDescription> GetFilterDescriptionss(Type filterType)
        {
            ICollection<FilterHolder> list = GetList(filterType);
            List<FilterDescription> ret = new List<FilterDescription>();
            foreach (FilterHolder holder in list)
            {
                ret.Add(holder.FilterDescription);
            }
            return ret;
        }

        public bool Exists(Type filterType, string id)
        {
            ICollection<FilterHolder> list = GetList(filterType);
            foreach (FilterHolder holder in list)
            {
                if (holder.FilterDescription.Id == id)
                    return true;
            }
            return false;
        }

        public BaseFilter GetFilterInstance(Type filterType, string id)
        {
            FilterHolder found = null;
            ICollection<FilterHolder> list = GetList(filterType);
            foreach (FilterHolder holder in list)
            {
                if (holder.FilterDescription.Id == id)
                    found = holder;
            }

            if (found == null)
                throw new ArgumentException("filter not found for type " + filterType + " with id " + id);

            return (BaseFilter)found.FilterInstance.Clone();
        }

        protected ICollection<FilterHolder> GetList(Type filterType)
        {
            if (!typesHolders.ContainsKey(filterType))
                return EmptyCollection<FilterHolder>.Instance;

            List<FilterHolder> list = typesHolders[filterType];
            Assert.CheckNotNull(list);

            return list;
        }

        public void Add(Type filterType, FilterDescription filterDescription, BaseFilter filterInstance)
        {
            if (filterType == null)
                throw new ArgumentException("filterType");

            if (filterInstance == null)
                throw new ArgumentException("filterInstance");

            if (filterDescription == null)
                throw new ArgumentException("filterDescription");

            if (Exists(filterType, filterDescription.Id))
                throw new ArgumentException("filter already exists for type " + filterType + " with id " + filterDescription.Id);

            if (!typesHolders.ContainsKey(filterType))
                typesHolders[filterType] = new List<FilterHolder>();

            typesHolders[filterType].Add(new FilterHolder(filterDescription, filterInstance));

        }
    }
}